package com.wolf.etl.core.handler;

import com.alibaba.fastjson.JSONObject;
import com.wolf.etl.core.ETLManager;
import com.wolf.etl.enumeration.HANDLER_TYPE;
import com.wolf.etl.model.EtlHandlerModel;

import java.io.IOException;
import java.util.*;

/**
 * 处理责任链
 *
 * @author sdyang
 * @date 2019/11/23 10:53
 **/
public class HandlerChain {

    private ETLManager manager;

    // 责任链中的处理器优先级排序集合
    private List<Float> offsets = new ArrayList<>();
    // 责任链的处理类集合
    private final Map<Float, AbstractHandler> handlerMap = new LinkedHashMap<>();

    public HandlerChain(ETLManager etlManager) {
        this.manager = etlManager;
        try {
            generateInstances();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static final String getPackageName() {
        return new Object() {
            public String getClassForStatic() {
                return this.getClass().getPackage().getName();
            }
        }.getClassForStatic();
    }

    /**
     * 扫描指定的包名，获取包下所有的类并创建实例
     *
     * @throws IOException
     */
    public void generateInstances() throws IOException {

        List<EtlHandlerModel> handlerList = manager.findHandlerList();
        for (EtlHandlerModel handler : handlerList) {
            offsets.add(handler.getOrder_num());
            Class<?> clazz = null;
            AbstractHandler abstractHandler = null;
            try {
                if (handler.getHandler_type().equalsIgnoreCase(HANDLER_TYPE.API.toString())) {
                    clazz = Class.forName(String.format("%s.%s", getPackageName(), "ApiHandler"));
                } else {
                    clazz = Class.forName(String.format("%s.%s", getPackageName(), "JavascriptHandler"));
                }
                abstractHandler = (AbstractHandler) manager.getBeanManager().createBean(clazz);
                abstractHandler.setHandler_id(handler.getHandler_id());
                abstractHandler.setManager(manager);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

            handlerMap.put(handler.getOrder_num(), abstractHandler);
        }

        // 升序排序
        Collections.sort(offsets);

        // 指定处理器的下一个处理器实例
        handlerMap.forEach((k, v) -> {
            int size = offsets.size() - 1;
            int index = offsets.indexOf(k);
            if (size > index) {
                v.setNextHandler(handlerMap.get(offsets.get(index + 1)));
            }
        });
    }

    /**
     * 处理器执行类（总是从链首开始执行）
     */
    public JSONObject done(JSONObject data) {
        if (offsets.size() == 0) {
            return data;
        }
        return handlerMap.get(offsets.get(0)).done(data);
    }


    public ETLManager getManager() {
        return manager;
    }

    public void setManager(ETLManager manager) {
        this.manager = manager;
    }
}
